#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <time.h>
#include <pthread.h>

#define MAX 256
#define SERVER_HOST "localhost"
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 13312

struct sockaddr_in server_addr, client_addr;
int mysock, csock; // socket descriptors
int r, len, n;     // help variables
time_t nowtime;

int server_init()
{
    printf("================== server init ======================\n");

    // create a TCP socket by socket() syscall
    printf("1 : create a TCP STREAM socket\n");
    mysock = socket(AF_INET, SOCK_STREAM, 0);

    if (mysock < 0)
    {
        printf("socket call failed\n");
        exit(1);
    }
    printf("2 : fill server_addr with host IP and PORT info\n");
    // initialize the server_addr structure
    server_addr.sin_family = AF_INET;                // for TCP/IP
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // This HOST IP
    server_addr.sin_port = htons(SERVER_PORT);       // port number 1234
    printf("3 : bind socket to server address\n");
    r = bind(mysock, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (r < 0)
    {
        printf("bind failed\n");
        exit(3);
    }
    printf(" hostname = %s port = %d\n", SERVER_HOST, SERVER_PORT);
    printf("4 : server is listening ....\n");
    listen(mysock, 5); // queue length = 5
    printf("=================== init done =======================\n");
}

static void Data_handle(void *sock_fd)
{
    int fd = *((int *)sock_fd);
    char buff[MAX];
    while (1)
    {   
        
        nowtime = time(NULL);
        printf("%s", ctime(&nowtime));
        sprintf(buff, "客户端IP： 127.0.0.1 \n 服务器实现者学号：20191312\n当前时间： %s", ctime(&nowtime));
        write(csock, buff, MAX);
        printf("server: ready for next request\n");
        sleep(2);
    }


    //Clear
    printf("terminating current client_connection...\n");
    close(fd);          //close a file descriptor.
    pthread_exit(NULL); //terminate calling thread!
}

int main()
{
    char line[MAX];
    pthread_t thread_id;
    server_init();
    while (1)
    { // Try to accept a client request
        printf("server: accepting new connection ....\n");
        // Try to accept a client connection as descriptor newsock
        len = sizeof(client_addr);
        csock = accept(mysock, (struct sockaddr *)&client_addr, &len);
        if (csock < 0)
        {
            printf("server: accept error\n");
            exit(1);
        }
        printf("server: accepted a client connection from\n");
        printf("---------------------------------------------–\n");
        printf("Clinet: IP=%s port=%d\n",
               inet_ntoa(client_addr.sin_addr),
               ntohs(client_addr.sin_port));
        printf("---------------------------------------------–\n");

        // Processing loop: client_sock <== data ==> client
        if (pthread_create(&thread_id, NULL, (void *)(&Data_handle), (void *)(&csock)) == -1)
        {
            fprintf(stderr, "pthread_create error!\n");
            break; //break while loop
        }
    }
}
